/*
 * Copyright 2010 Chad Retz
 * 
 * Licensed under the Apache License, Version 2.0 (the "License"); you may not
 * use this file except in compliance with the License. You may obtain a copy of
 * the License at
 * 
 * http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 * License for the specific language governing permissions and limitations under
 * the License.
 */
package org.jdocng.parse.qdox.function;

import org.jdocng.parse.qdox.QDoxContext;
import org.jdocng.shared.model.MethodDocImpl;

import com.thoughtworks.qdox.model.JavaClass;
import com.thoughtworks.qdox.model.JavaMethod;

/**
 * Construct {@link MethodDocImpl} from {@link JavaMethod}
 *
 * @author Chad Retz
 */
public class MethodFunction extends ExecutableMemberFunction<MethodDocImpl> {

    private static final MethodFunction instance = new MethodFunction();
    
    public static MethodFunction getInstance() {
        return instance;
    }
    
    protected static JavaMethod getOverriddingMethod(JavaMethod method, 
            JavaClass classToCheck) {
        if (classToCheck == null) {
            return null;
        }
        for (JavaMethod parentMethod : classToCheck.getMethods()) {
            if (!parentMethod.isPrivate() && (parentMethod.isProtected() 
                    || !parentMethod.isPublic() ||
                    parentMethod.getParentClass().getPackageName().equals(
                            method.getParentClass().getPackageName())) &&
                    parentMethod.signatureMatches(method.getName(), 
                    method.getParameterTypes(), method.isVarArgs())) {
                return parentMethod;
            }
        }
        return getOverriddingMethod(method, classToCheck.getSuperJavaClass());
    }
    
    protected MethodFunction() {
    }
    
    @Override
    public void apply(QDoxContext context, JavaMethod from, MethodDocImpl to) {
        super.apply(context, from, to);
        //find overriding method
        JavaMethod overridding = getOverriddingMethod(from, 
                from.getParentClass().getSuperJavaClass());
        if (overridding != null) {
            to.setOverriddenClass(overridding.getParentClass().getFullyQualifiedName());
        }
        to.setReturnType(from.getReturnType().getFullyQualifiedName());
    }
    
    @Override
    public MethodDocImpl apply(QDoxContext context, JavaMethod from) {
        MethodDocImpl to = new MethodDocImpl();
        apply(context, from, to);
        return to;
    }

}
